/*
 * Init.c
 *
 *  Created on: Oct 15, 2018
 *      Author: ax
 */
#include <Type.h>
#include <Hw/Pdsp.h>
#include <Hw/Memory.h>

#include <ti/csl/src/ip/qmss/firmware.h>


#define W4_DESCS Qmss_FSZ32_DESC_NUM
#if (  (W4_DESCS != (0 <<  0)) && (W4_DESCS != (1 <<  5)) && (W4_DESCS != (1 <<  6)) \
    && (W4_DESCS != (1 <<  7)) && (W4_DESCS != (1 <<  8)) && (W4_DESCS != (1 <<  9)) \
    && (W4_DESCS != (1 << 10)) && (W4_DESCS != (1 << 11)) && (W4_DESCS != (1 << 12)) \
    && (W4_DESCS != (1 << 13)) && (W4_DESCS != (1 << 14)) && (W4_DESCS != (1 << 15)) )
#error W4_DESCS must be power of 2
#elif (W4_DESCS != 0)
char __descriptor(w4) hostW4Desc[W4_DESCS][16];
#endif

#define W8_DESCS Qmss_FSZ32_DESC_NUM
#if (  (W8_DESCS != (0 <<  0)) && (W8_DESCS != (1 <<  5)) && (W8_DESCS != (1 <<  6)) \
    && (W8_DESCS != (1 <<  7)) && (W8_DESCS != (1 <<  8)) && (W8_DESCS != (1 <<  9)) \
    && (W8_DESCS != (1 << 10)) && (W8_DESCS != (1 << 11)) && (W8_DESCS != (1 << 12)) \
    && (W8_DESCS != (1 << 13)) && (W8_DESCS != (1 << 14)) && (W8_DESCS != (1 << 15)) )
#error W8_DESCS must be power of 2
#elif (W8_DESCS != 0)
char __descriptor(w8) hostW8Desc[W8_DESCS][32];
#endif

#define W12_DESCS Qmss_FSZ48_DESC_NUM
#if (  (W12_DESCS != (0 <<  0)) && (W12_DESCS != (1 <<  5)) && (W12_DESCS != (1 <<  6)) \
    && (W12_DESCS != (1 <<  7)) && (W12_DESCS != (1 <<  8)) && (W12_DESCS != (1 <<  9)) \
    && (W12_DESCS != (1 << 10)) && (W12_DESCS != (1 << 11)) && (W12_DESCS != (1 << 12)) \
    && (W12_DESCS != (1 << 13)) && (W12_DESCS != (1 << 14)) && (W12_DESCS != (1 << 15)) )
#error W12_DESCS must be power of 2
#elif (W12_DESCS != 0)
char __descriptor(w12) hostW12Desc[W12_DESCS][48];
#endif

#define W16_DESCS Qmss_FSZ64_DESC_NUM
#if (  (W16_DESCS != (0 <<  0)) && (W16_DESCS != (1 <<  5)) && (W16_DESCS != (1 <<  6)) \
    && (W16_DESCS != (1 <<  7)) && (W16_DESCS != (1 <<  8)) && (W16_DESCS != (1 <<  9)) \
    && (W16_DESCS != (1 << 10)) && (W16_DESCS != (1 << 11)) && (W16_DESCS != (1 << 12)) \
    && (W16_DESCS != (1 << 13)) && (W16_DESCS != (1 << 14)) && (W16_DESCS != (1 << 15)) )
#error W16_DESCS must be power of 2
#elif (W16_DESCS != 0)
char __descriptor(w16) hostW16Desc[W16_DESCS][64];
#endif

#define W32_DESCS Qmss_FSZ128_DESC_NUM
#if (  (W32_DESCS != (0 <<  0)) && (W32_DESCS != (1 <<  5)) && (W32_DESCS != (1 <<  6)) \
    && (W32_DESCS != (1 <<  7)) && (W32_DESCS != (1 <<  8)) && (W32_DESCS != (1 <<  9)) \
    && (W32_DESCS != (1 << 10)) && (W32_DESCS != (1 << 11)) && (W32_DESCS != (1 << 12)) \
    && (W32_DESCS != (1 << 13)) && (W32_DESCS != (1 << 14)) && (W32_DESCS != (1 << 15)) )
#error W32_DESCS must be power of 2
#elif (W32_DESCS != 0)
char __descriptor(w32) hostW32Desc[W32_DESCS][128];
#endif

#define MONO_DESC_NUM       QMSS_MONO_DESC_NUM
#if (  (MONO_DESC_NUM != (0 <<  0)) && (MONO_DESC_NUM != (1 <<  5)) && (MONO_DESC_NUM != (1 <<  6)) \
    && (MONO_DESC_NUM != (1 <<  7)) && (MONO_DESC_NUM != (1 <<  8)) && (MONO_DESC_NUM != (1 <<  9)) \
    && (MONO_DESC_NUM != (1 << 10)) && (MONO_DESC_NUM != (1 << 11)) && (MONO_DESC_NUM != (1 << 12)) \
    && (MONO_DESC_NUM != (1 << 13)) && (MONO_DESC_NUM != (1 << 14)) && (MONO_DESC_NUM != (1 << 15)) )
#error MONO_DESC_NUM must be power of 2
#elif (MONO_DESC_NUM != 0)
#pragma DATA_SECTION(qmssMonoDesc,".Qmss.desc:mono")
#pragma DATA_ALIGN (qmssMonoDesc, 64)
char qmssMonoDesc[MONO_DESC_NUM][MONO_DESC_SIZE];
#endif

#include <Hw/Qmss.h>
#define TOTAL_LINK_RAM_CNT  (MONO_DESC_NUM + W8_DESCS + W16_DESCS + W32_DESCS)
#if (TOTAL_LINK_RAM_CNT > Qmss_INTERNAL_LINK_RAM_DSEC_SUPPORT)
#define EXT_LNK_RAM_DESC_NUM    (TOTAL_LINK_RAM_CNT - INTERNAL_LINK_RAM_DSEC_SUPPORT)
Uint64 __attribute__((aligned(16), section(".linkram"))) linkingRamExt[EXT_LNK_RAM_DESC_NUM];
#define EXT_LNK_RAM &linkingRamExt
#error descriptor > Qmss_INTERNAL_LINK_RAM_DSEC_SUPPORT not supported right now.
#else
#define EXT_LNK_RAM_DESC_NUM    0
#define EXT_LNK_RAM             (void*)0
#endif//TOTAL_LINK_RAM_CNT


Status __init
Qmss_setup(void) {
    Qmss_init(EXT_LNK_RAM, EXT_LNK_RAM_DESC_NUM);

    Queue q;
    for (q = 0; q < Queue_MAX; q++)
        Qmss_empty(q);

    #if Qmss_FSZ16_DESC_NUM
    Qmss_descriptorSetup((PtrVal) hostW4Desc, Qmss_FSZ16_DESC_NUM,
             Desc_SIZE16, Descriptor_HOST_PACKET, Queue_HPOOL(Desc_SIZE16));
    #endif
    #if Qmss_FSZ32_DESC_NUM
    Qmss_descriptorSetup((PtrVal) hostW8Desc, Qmss_FSZ32_DESC_NUM,
             Desc_SIZE32, Descriptor_HOST_PACKET, Queue_HPOOL(Desc_SIZE32));
    #endif
    #if Qmss_FSZ48_DESC_NUM
    Qmss_descriptorSetup((PtrVal) hostW12Desc, Qmss_FSZ48_DESC_NUM,
             Desc_SIZE48, Descriptor_HOST_PACKET, Queue_HPOOL(Desc_SIZE48));
    #endif
    #if Qmss_FSZ64_DESC_NUM
    Qmss_descriptorSetup((PtrVal) hostW16Desc, Qmss_FSZ64_DESC_NUM,
             Desc_SIZE64, Descriptor_HOST_PACKET, Queue_HPOOL(Desc_SIZE64));
    #endif
    #if Qmss_FSZ128_DESC_NUM
    Qmss_descriptorSetup((PtrVal) hostW32Desc, Qmss_FSZ128_DESC_NUM,
             Desc_SIZE128, Descriptor_HOST_PACKET, Queue_HPOOL(Desc_SIZE128));
    #endif

    #if _BIG_ENDIAN
    #if Pdsp_ACC_48_CHANNEL
    Pdsp_firmwareLoad(Qmss_PDSP1, &acc48_be, sizeof(acc48_be));
    #else
    Pdsp_firmwareLoad(Qmss_PDSP1, &acc32_be, sizeof(acc32_be));
    Pdsp_firmwareLoad(Qmss_PDSP2, &acc16_be, sizeof(acc16_be));
    #endif
    #else
    #if Pdsp_ACC_48_CHANNEL
    Pdsp_firmwareLoad(Qmss_PDSP1, &acc48_le, sizeof(acc48_le));
    #else
    Pdsp_firmwareLoad(Qmss_PDSP1, &acc32_le, sizeof(acc32_le));
    Pdsp_firmwareLoad(Qmss_PDSP2, &acc16_le, sizeof(acc16_le));
    #endif
    #endif

    Qmss_start();

    Pdsp_reclaimQueueSetup(Qmss_PDSP1, Queue_RECLAIM);

    return OK;
}
